#include "BaseDialog.h"
#include "MainWindow.h"

#include <QGuiApplication>
#include <QBoxLayout>
#include <QScreen>
#include <QGraphicsEffect>
#include <QBitmap>
#include <QPainter>

extern bool canUseCompositing();

BaseDialog::BaseDialog(QWidget *parent)
    : QDialog(parent)
    , Frameless(this)
    , m_overlayWidget(nullptr)
{

}

void BaseDialog::done(int result)
{
    return QDialog::done(result);
}

void BaseDialog::showEvent(QShowEvent *event)
{
    QRect screenRect = qApp->primaryScreen()->geometry();
    QRect rect(this->rect());
    rect.moveCenter(screenRect.center());

    move(rect.topLeft());
    return QDialog::showEvent(event);
}

void BaseDialog::initGraphicsEffect(QWidget *widget)
{
    QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect(widget);
    effect->setBlurRadius(20);
    effect->setColor(QColor(0, 0, 0, 0.3*255));
    effect->setOffset(0);
    widget->setGraphicsEffect(effect);
}

QBitmap BaseDialog::updateRegionMask(const QSize &size)
{
    static QBitmap bitmap;
    if (bitmap.size() != size) {
        // update bitmap
        bitmap = QBitmap(size);
        bitmap.fill(Qt::color0);

        QPainter bPainter(&bitmap);
        bPainter.setRenderHint(QPainter::Antialiasing);
        bPainter.setPen(Qt::NoPen);
        bPainter.setBrush(Qt::color1);
        bPainter.drawRoundedRect(bitmap.rect(), 10, 10);
        bPainter.end();
    }

    return bitmap;
}

bool BaseDialog::withDropShadow()
{
    return canUseCompositing();
}

QMargins BaseDialog::layoutMargins()
{
    return QMargins(10, 10, 10, 10);
}

bool BaseDialog::canWindowMove()
{
    return true;
}

bool BaseDialog::event(QEvent *event)
{
    Frameless::event(event);
    do {
        const auto &layout = this->layout();
        if (event->type() == QEvent::PolishRequest) {
            auto enabledGraphcs = (layout->count() == 1);
            if (!enabledGraphcs)
                break;

            QWidget *graphicsWidget = layout->itemAt(0)->widget();
            Q_ASSERT(graphicsWidget);

            if (withDropShadow()) {
                if (graphicsWidget->graphicsEffect())
                    break;
                layout->setMargin(10);
                initGraphicsEffect(graphicsWidget);
            } else {
                layout->setMargin(0);
                if (auto effect = graphicsWidget->graphicsEffect()) {
                    effect->deleteLater();
                }
            }
        } else if (event->type() == QEvent::Resize) {
            auto enabledMask = (layout->count() == 1);
            if (!enabledMask)
                break;

            QWidget *centerWidget = layout->itemAt(0)->widget();
            Q_ASSERT(centerWidget);

            QSize size = this->size();
            if (withDropShadow()) {
                size = centerWidget->size();
            }
            // TODO: this function is very slow, modify it.
            centerWidget->setMask(updateRegionMask(size));
        }
    } while (false);


    return QDialog::event(event);
}

void BaseDialog::mousePressEvent(QMouseEvent *event)
{
    if (Frameless::mousePressEvent(event))
        return;

    return QDialog::mousePressEvent(event);
}

void BaseDialog::mouseReleaseEvent(QMouseEvent *event)
{
    QDialog::mouseReleaseEvent(event);
    return Frameless::mouseReleaseEvent(event);
}

void BaseDialog::mouseMoveEvent(QMouseEvent *event)
{
    QDialog::mouseMoveEvent(event);
    return Frameless::mouseMoveEvent(event);
}

void BaseDialog::focusInEvent(QFocusEvent *event)
{
    Frameless::focusInEvent(event);
    return QDialog::focusInEvent(event);
}

bool BaseDialog::canResize()
{
    return false;
}

